﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace XLang
{
    /// <summary>
    /// Token规则
    /// </summary>
    public class TokenRule
    {
        public List<string> State { get; set; }

        public Type Type { get; set; }

        public Func<LContext, object> Create { get; set; }

        public TokenRule(Type type)
        {
            #region 状态
            var stateAttributes = type.GetCustomAttributes(typeof(StateAttribute), false);
            this.State = new List<string>();
            if (stateAttributes.Length == 0)
            {
                this.State.Add("Initial");
            }
            else
            {
                foreach (var stateObj in stateAttributes)
                {
                    var state = (StateAttribute)stateObj;
                    this.State.Add(state.Value);
                }
            }
            #endregion

            #region Create
            this.Type = type;

            MethodInfo mi = null;
            var methods = type.GetMethods();
            foreach (var method in methods)
            {
                if (method.Name != "Token" || !method.IsStatic) continue;

                if (method.ReturnType != typeof(string) && !method.ReturnType.IsInherit(typeof(Token))) continue;

                var parameters = method.GetParameters();
                if (parameters.Length == 1 && parameters[0].ParameterType == typeof(LContext))
                {
                    mi = method;
                }
            }

            if (mi == null) throw new Exception("Token class must have a Token method.");

            this.Create = (context) =>
            {
                return mi.Invoke(null, new[] { context });
            };
            #endregion
        }
    }
}
